import { ref, computed } from 'vue';
import { invoke } from '@tauri-apps/api/core';
import type { DirEntry, TreeNode } from '../stores/workspace';

// 索引构建状态
export interface IndexingProgress {
  phase: 'idle' | 'scanning' | 'building' | 'complete' | 'error';
  currentPath: string;
  processedCount: number;
  totalCount: number;
  startTime?: number;
  endTime?: number;
  error?: string;
}

// 索引数据结构
export interface DirectoryIndex {
  [dirPath: string]: {
    children: TreeNode[];
    lastScanned: number;
    isComplete: boolean;
  };
}

class WorkspaceIndexer {
  private static _instance: WorkspaceIndexer | null = null;
  
  static get instance(): WorkspaceIndexer {
    if (!this._instance) {
      this._instance = new WorkspaceIndexer();
    }
    return this._instance;
  }

  // 索引状态
  private _progress = ref<IndexingProgress>({
    phase: 'idle',
    currentPath: '',
    processedCount: 0,
    totalCount: 0
  });

  private _index = ref<DirectoryIndex>({});
  private _isIndexing = ref(false);
  
  // 取消控制
  private _abortController: AbortController | null = null;
  
  // 公开的响应式属性
  get progress() { return this._progress; }
  get index() { return this._index; }
  get isIndexing() { return this._isIndexing; }

  // 计算属性：索引完成百分比
  get progressPercent() {
    return computed(() => {
      const { processedCount, totalCount } = this._progress.value;
      if (totalCount === 0) return 0;
      return Math.round((processedCount / totalCount) * 100);
    });
  }

  // 计算属性：预估剩余时间
  get estimatedTimeRemaining() {
    return computed(() => {
      const { phase, processedCount, totalCount, startTime } = this._progress.value;
      if (phase !== 'scanning' && phase !== 'building') return null;
      if (!startTime || processedCount === 0) return null;
      
      const elapsed = Date.now() - startTime;
      const avgTimePerItem = elapsed / processedCount;
      const remaining = totalCount - processedCount;
      
      return Math.round((remaining * avgTimePerItem) / 1000); // 返回秒数
    });
  }

  /**
   * 开始构建工作区索引
   */
  async buildIndex(rootPath: string, options: {
    maxDepth?: number;
    excludePatterns?: string[];
    onProgress?: (progress: IndexingProgress) => void;
    force?: boolean; // 新增：是否强制重新索引
  } = {}): Promise<boolean> {
    const { force = false } = options;
    
    if (this._isIndexing.value && !force) {
      console.log('[WorkspaceIndexer] Indexing already in progress, skipping duplicate request');
      return false;
    }
    
    // 如果是强制重新索引，先取消当前索引
    if (force && this._isIndexing.value) {
      console.log('[WorkspaceIndexer] Force rebuilding index, cancelling current indexing...');
      this.cancelIndexing();
      // 等待取消完成
      await new Promise(resolve => setTimeout(resolve, 100));
    }

    this._isIndexing.value = true;
    this._abortController = new AbortController();
    
    const { maxDepth = 10, excludePatterns = [], onProgress } = options;
    
    try {
      // 初始化进度
      this._progress.value = {
        phase: 'scanning',
        currentPath: rootPath,
        processedCount: 0,
        totalCount: 0,
        startTime: Date.now()
      };

      if (onProgress) onProgress(this._progress.value);

      // 第一阶段：递归扫描目录结构，计算总数
      const totalDirs = await this.countDirectories(rootPath, maxDepth, excludePatterns);
      
      this._progress.value.totalCount = totalDirs;
      this._progress.value.phase = 'building';
      
      if (onProgress) onProgress(this._progress.value);

      // 第二阶段：递归构建索引
      await this.buildDirectoryIndex(rootPath, 0, maxDepth, excludePatterns, onProgress);

      // 完成
      this._progress.value.phase = 'complete';
      this._progress.value.endTime = Date.now();
      
      if (onProgress) onProgress(this._progress.value);
      
      console.log(`Workspace indexing completed. Indexed ${this._progress.value.processedCount} directories.`);
      return true;

    } catch (error) {
      console.error('Workspace indexing failed:', error);
      this._progress.value.phase = 'error';
      this._progress.value.error = String(error);
      
      if (onProgress) onProgress(this._progress.value);
      return false;

    } finally {
      this._isIndexing.value = false;
      this._abortController = null;
    }
  }

  /**
   * 取消索引构建
   */
  cancelIndexing(): void {
    if (this._abortController) {
      this._abortController.abort();
    }
  }

  /**
   * 获取指定目录的已构建索引
   */
  getIndexedChildren(dirPath: string): TreeNode[] | null {
    try {
      const normalizedPath = this.normalizePath(dirPath);
      const indexValue = this._index.value;
      
      // 安全检查：确保索引对象存在
      if (!indexValue || typeof indexValue !== 'object') {
        return null;
      }
      
      const entry = indexValue[normalizedPath];
      return entry?.children || null;
    } catch (error) {
      console.warn('Failed to get indexed children for path:', dirPath, error);
      return null;
    }
  }

  /**
   * 检查目录是否已被索引
   */
  isDirectoryIndexed(dirPath: string): boolean {
    try {
      const normalizedPath = this.normalizePath(dirPath);
      const indexValue = this._index.value;
      
      // 安全检查：确保索引对象存在
      if (!indexValue || typeof indexValue !== 'object') {
        return false;
      }
      
      return !!indexValue[normalizedPath]?.isComplete;
    } catch (error) {
      console.warn('Failed to check if directory is indexed:', dirPath, error);
      return false;
    }
  }

  /**
   * 增量更新指定目录的索引
   */
  async updateDirectoryIndex(dirPath: string): Promise<void> {
    try {
      const children = await this.scanDirectory(dirPath);
      const normalizedPath = this.normalizePath(dirPath);
      
      this._index.value[normalizedPath] = {
        children,
        lastScanned: Date.now(),
        isComplete: true
      };
    } catch (error) {
      console.warn('Failed to update directory index:', dirPath, error);
    }
  }

  /**
   * 清空索引
   */
  clearIndex(): void {
    this._index.value = {};
    this._progress.value = {
      phase: 'idle',
      currentPath: '',
      processedCount: 0,
      totalCount: 0
    };
  }

  // 私有方法：计算目录总数
  private async countDirectories(
    dirPath: string, 
    maxDepth: number, 
    excludePatterns: string[],
    currentDepth = 0
  ): Promise<number> {
    if (currentDepth >= maxDepth) return 0;
    if (this._abortController?.signal.aborted) throw new Error('Indexing cancelled');
    
    if (this.shouldExclude(dirPath, excludePatterns)) return 0;

    try {
      const entries = await this.readDirectory(dirPath);
      let count = 1; // 当前目录计数

      for (const entry of entries) {
        if (entry.isDir) {
          count += await this.countDirectories(entry.path, maxDepth, excludePatterns, currentDepth + 1);
        }
      }

      return count;
    } catch {
      return 0;
    }
  }

  // 私有方法：递归构建目录索引
  private async buildDirectoryIndex(
    dirPath: string,
    currentDepth: number,
    maxDepth: number,
    excludePatterns: string[],
    onProgress?: (progress: IndexingProgress) => void
  ): Promise<void> {
    if (currentDepth >= maxDepth) return;
    if (this._abortController?.signal.aborted) throw new Error('Indexing cancelled');
    
    if (this.shouldExclude(dirPath, excludePatterns)) return;

    try {
      // 更新进度
      this._progress.value.currentPath = dirPath;
      this._progress.value.processedCount++;
      
      if (onProgress) onProgress(this._progress.value);

      // 扫描当前目录
      const children = await this.scanDirectory(dirPath);
      
      // 存储索引
      const normalizedPath = this.normalizePath(dirPath);
      this._index.value[normalizedPath] = {
        children,
        lastScanned: Date.now(),
        isComplete: true
      };

      // 递归处理子目录
      for (const child of children) {
        if (child.isDir) {
          await this.buildDirectoryIndex(
            child.id, 
            currentDepth + 1, 
            maxDepth, 
            excludePatterns, 
            onProgress
          );
        }
      }
    } catch (error) {
      console.warn('Failed to index directory:', dirPath, error);
    }
  }

  // 私有方法：扫描单个目录
  private async scanDirectory(dirPath: string): Promise<TreeNode[]> {
    try {
      const entries = await this.readDirectory(dirPath);
      return entries.map(entry => ({
        id: entry.path,
        label: entry.name,
        isDir: !!(entry.is_dir || entry.isDir || entry.isFolder)
      }));
    } catch {
      return [];
    }
  }

  // 私有方法：读取目录内容
  private async readDirectory(dirPath: string): Promise<DirEntry[]> {
    try {
      const entries = await invoke<DirEntry[]>('fs_read_dir', { path: dirPath });
      return Array.isArray(entries) ? entries : [];
    } catch {
      return [];
    }
  }

  // 私有方法：路径规范化
  private normalizePath(path: string): string {
    let s = String(path || '').replace(/\\/g, '/');
    if (s.length > 3) s = s.replace(/\/+$/g, '');
    if (/^[a-zA-Z]:\//.test(s)) s = s.toLowerCase();
    return s;
  }

  // 私有方法：检查是否应该排除路径
  private shouldExclude(path: string, excludePatterns: string[]): boolean {
    if (!excludePatterns.length) return false;
    
    const normalizedPath = path.toLowerCase();
    return excludePatterns.some(pattern => {
      const regex = new RegExp(
        pattern.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
              .replace(/\\\*/g, '.*')
              .replace(/\\\?/g, '.'), 
        'i'
      );
      return regex.test(normalizedPath);
    });
  }
}

export const workspaceIndexer = WorkspaceIndexer.instance;